<script setup>
import {shallowRef} from "vue";
import {getResponseData} from "../util";
import {ElMessage} from "element-plus";

// 上传控件对象
let uploader = shallowRef();

// 当前token值
let currentToken = sessionStorage.getItem('token');

/**
 * name: 控件名称，对应后台API接口中的文件参数名
 * action: 上传地址，对应后台API接口地址
 * fn: 上传成功后的回调函数
 * drag: 是否允许拖拽上传
 * limit: 单次文件上传的最大数量限制，默认 1
 * showFileList: 是否显示上传的文件列表，默认 true
 * autoUpload: 是否自动上传，默认 false
 * btnLabel: 上传提交按钮文案，默认 "确认上传"
 * btnType: 上传提交按钮主题颜色，默认 "warning"
 * successTip: 上传成功后的提示信息
 * allowTypes: 支持上传的MIME格式数组 默认 ['image/jpeg', 'image/png']
 * maxSize: 支持上传的文件最大限制，单位MB，默认10M
 */
let parent = defineProps({
  'name': {type: String, required: true},
  'action': {type: String, required: true},
  'fn': {type: Function, required: false},
  'drag': {type: Boolean, required: false, default: true},
  'limit': {type: Number, required: false, default: 1},
  'showFileList': {type: Boolean, required: false, default: true},
  'autoUpload': {type: Boolean, required: false, default: false},
  'btnLabel': {type: String, required: false, default: '确认上传'},
  'btnType': {type: String, required: false, default: 'warning'},
  'successTip': {type: String, required: false, default: '上传成功！'},
  'allowTypes': {type: Array, required: false, default: ['image/jpeg', 'image/png']},
  'maxSize': {type: Number, required: false, default: 10},
});

/*
 * 文件上传前的校验过程
 *
 * @param file 文件对象，必传
 * @return true校验成功，false校验失败
 */
function beforeUpload(file) {
  let allowTypes = parent['allowTypes'];
  let maxSize = parent['maxSize'];

  // 空值保护
  if (!file || !allowTypes) return false;

  // 校验文件MIME类型
  if (!allowTypes.includes(file.type)) {
    ElMessage.warning(`仅支持 ${allowTypes.toString()} 格式！`);
    return false;
  }

  // 校验文件大小
  if (file.size / 1024 / 1024 > maxSize) {
    ElMessage.error(`文件大小不能超过 ${maxSize} MB`)
    return false;
  }

  return true;
}

// 上传文件成功后: 解析响应 + 清空上传控件的文件列表 + 成功提示 + 回调函数
async function onSuccess(res) {
  let data = getResponseData(res);
  if (data) {
    uploader.value.clearFiles();
    if (parent['successTip']) ElMessage.success(parent['successTip']);
    if (parent['fn']) await parent['fn']();
  }
}

</script>

<template>
<el-upload class="my-uploader" ref="uploader" list-type="picture"
           :name="name"
           :action="action"
           :headers="{'token': currentToken}"
           :drag="drag"
           :limit="limit"
           :show-file-list="showFileList"
           :auto-upload="autoUpload"
           :before-upload="beforeUpload"
           :on-success="onSuccess">
  <el-link class="el-icon--upload" icon="UploadFilled" :underline="false"/>
  <div class="el-upload__text">拖拽文件 或 <em>点击上传</em></div>
  <template #tip>
    <div class="el-upload__tip">
      仅支持 {{ allowTypes.toString() }} 格式，且单个文件不超过 {{ maxSize }} MB
    </div>
  </template>
</el-upload>

<!--上传按钮-->
<el-button v-if="!autoUpload" class="upload-btn" :type="btnType" @click="uploader.submit()">
  {{ btnLabel }}
</el-button>
</template>

<style scoped lang="scss">
.upload-btn {
  margin-top: 10px; // 上外边距
  width: 100%; // 宽度
}

</style>